<?php

use Illuminate\Database\Capsule\Manager as Capsule;
use Monolog\Formatter\JsonFormatter;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Illuminate\Events\Dispatcher;
use Illuminate\Container\Container;
use OpenApi\Generator as OpenApiGenerator;

/**
 * @name Bootstrap
 * @author xmwg6125\ccuser
 * @desc 所有在Bootstrap类中, 以_init开头的方法, 都会被Yaf调用,
 * @see http://www.php.net/manual/en/class.yaf-bootstrap-abstract.php
 * 这些方法, 都接受一个参数:\Yaf\Dispatcher $dispatcher
 * 调用的次序, 和申明的次序相同
 */
class Bootstrap extends \Yaf\Bootstrap_Abstract {

    public function _initConfig() {
		//把配置保存起来
		$arrConfig = \Yaf\Application::app()->getConfig();
		\Yaf\Registry::set('config', $arrConfig);
	}

    public function _initLoader(Yaf\Dispatcher $dispatcher) {
//        $loader = Yaf\Loader::getInstance();
//        $loader->registerLocalNamespace(array('App'));
    }
    public function _initSwagger()
    {
        // 生成OpenAPI规范
        $spec = OpenApiGenerator::scan([APPLICATION_PATH . '/application/controllers'], [
            'info.title' => 'My Yaf Application API',
            'info.version' => '1.0.0',
        ]);
        // 将规范保存到文件
        file_put_contents(APPLICATION_PATH . '/public/swagger.json', $spec->toJson());
    }

    public function _initLogger() {
        $var = \Yaf\Registry::get('config');

        // 创建日志实例
        $logger = new Logger('yaf_app');

        // 设置日志处理器，日志将写入 logs/app.log 文件
        $logFile = __DIR__ . '/../logs/app.log';
        $streamHandler = new StreamHandler($logFile, Logger::DEBUG);
        $logger->pushHandler($streamHandler);
//        $jsonFormatter = new JsonFormatter();
//        $streamHandler->setFormatter($jsonFormatter);
        // 将 logger 存储到注册表中，方便后续使用
        \Yaf\Registry::set('logger', $logger);
    }

	public function _initPlugin(\Yaf\Dispatcher $dispatcher) {
		//注册一个插件
		$objSamplePlugin = new SamplePlugin();
		$dispatcher->registerPlugin($objSamplePlugin);

	}

    public function _initEloquent() {
        $config = \Yaf\Application::app()->getConfig()->database;
        $capsule = new Capsule;

        $capsule->addConnection([
            'driver'    => $config->driver,
            'host'      => $config->host,
            'database'  => $config->database,
            'username'  => $config->username,
            'password'  => $config->password,
            'charset'   => $config->charset,
            'collation' => $config->collation,
            'prefix'    => $config->prefix,
        ]);

        // Set the capsule instance globally
        $capsule->setAsGlobal();
        // Boot Eloquent ORM
        $capsule->bootEloquent();

        // 设置Eloquent的日志记录器
        $capsule->getConnection()->enableQueryLog();
        $capsule->getConnection()->setEventDispatcher(new Dispatcher(new Container));
        $log = \Yaf\Registry::get('logger');
        $capsule->getConnection()->listen(function ($sql) use ($log) {

            foreach ($sql->bindings as $i => $binding) {
                if ($binding instanceof \DateTime) {
                    $sql->bindings[$i] = $binding->format('\'Y-m-d H:i:s\'');
                } else {
                    if (is_string($binding)) {
                        $sql->bindings[$i] = "'$binding'";
                    }
                }
            }
            // Insert bindings into query
            $query = str_replace(array('%', '?'), array('%%', '%s'), $sql->sql);
            $query = vsprintf($query, $sql->bindings);
            // 将SQL语句和执行时间（秒）写入日志文件
            $log->info($query, [
                'time' =>  sprintf("%.4f", $sql->time / 1000) // 将毫秒转换为秒
            ]);
        });
    }

	public function _initRoute(\Yaf\Dispatcher $dispatcher) {
        //在这里注册自己的路由协议,默认使用简单路由
        $router = $dispatcher->getRouter();
	}
	
	public function _initView(\Yaf\Dispatcher $dispatcher) {
		//在这里注册自己的view控制器，例如smarty,firekylin
	}

    public function _initRoutes(\Yaf\Dispatcher $dispatcher) {
        $router = $dispatcher->getRouter();
        // 自定义路由规则
    }

    /**
     * 初始化错误处理函数
     * @param Yaf_Dispatcher $dispatcher
     */
    public function _initErrorHandle(Yaf\Dispatcher $dispatcher)
    {
        // 设置调度器的错误处理函数
//        $dispatcher->setErrorHandler([$this, 'customErrorHandler'], E_ALL);
    }

    /**
     * 自定义异常捕获函数
     * @param $errno - 报错级别
     * @param $errstr - 报错内容
     * @param $errfile - 报错文件
     * @param $errline - 报错文件行号
     * @return false
     */
    public function customErrorHandler($errno, $errstr, $errfile, $errline)
    {
        // 抛出异常
        throw new ErrorException($errstr, 50001, $errno, $errfile, $errline);
        // 继续执行默认的错误处理机制
        return false;
    }
//    public function handleException($exception) {
//        echo "111";
//        throw new Exception( $exception->getMessage());
//    }
}
